Fox's Git Mirrors
docs/en/architecture.md 83609bcb589eb3cfc35b98ecc0b3327b2ae99d77 (83609bcb) Text, 10.19 KB
Architecture
Purpose of this document
This page explains how Reticulum-Go is structured, describing layers, control flow, persistence, and deployment patterns.
Layered model
Reticulum-Go follows the same conceptual layers as Python Reticulum:
T282828
+-------------------------------------------------------------+
| Application (your code, examples, control API clients) |
+-------------------------------------------------------------+
| Destination, Link, Resource, Channel, Buffer |
+-------------------------------------------------------------+
| Transport (routing, path table, announces, relay) |
+-------------------------------------------------------------+
| Interface (UDP, TCP, Auto, I2P, Backbone, WebSocket, QUIC) |
+-------------------------------------------------------------+
| OS sockets, SAM, multicast, shared-instance multiplexer |
+-------------------------------------------------------------+
Each layer depends downward only. Interfaces know nothing about application names. Destinations do not open raw sockets.
Runtime components
Daemon (T383838cmd/reticulum-go)
The daemon is the long-running process most operators deploy. On startup it:
1. Loads configuration from T383838~/.reticulum-go/config (or T383838--config)
2. Creates a T383838node.Node which owns transport and interfaces
3. Starts transport and registers each enabled interface
4. Optionally attaches to a shared instance (share_instance)
5. Applies the runtime sandbox (T383838pkg/sandbox) unless disabled
6. Optionally starts the control API on localhost
7. Handles T383838SIGHUP on Unix to hot-reload interface blocks
Shutdown on T383838SIGINT or T383838SIGTERM stops interfaces and flushes path persistence where configured.
Node (T383838pkg/node)
Node is the embedder-facing orchestration type. It wires:
• T383838transport.Transport for routing
• T383838interfaces.Interface instances from config
• T383838sharedinstance.Instance when sharing one Reticulum process on a host
• Optional T383838discovery.InterfaceDiscovery when discover_interfaces is enabled
• Network lifecycle hooks (OnNetworkAvailable, OnNetworkLost, RefreshPaths, ReloadInterfaces)
Library authors typically construct T383838node.New(cfg) and call T383838Start() rather than reimplementing transport registration.
Transport (T383838pkg/transport)
Transport is the routing engine. It maintains:
• A path table mapping destination hashes to next-hop interface and hop count
• Registered destinations and their packet receivers
• Link table entries for established sessions
• Announce handlers and ingress or egress rate limits
• Optional on-disk persistence for paths and known destinations
Every interface registers a callback that feeds inbound bytes into T383838Transport.HandlePacket.
Interfaces (T383838pkg/interfaces)
Interfaces translate between Reticulum packets and a physical medium. They handle:
• IFAC mask and unmask on ingress and egress (T383838pkg/common)
• HDLC framing for TCP and backbone clients
• Reconnect loops for TCP, UDP (opt-in), I2P, and backbone clients
• Platform-specific socket options (IPv6 preference, bind addresses)
Factory entry point: T383838interfaces.NewFromConfigWithContext.
Shared instance (T383838pkg/sharedinstance)
When T383838share_instance = yes, only one Reticulum process on a host should own the real interfaces. Other processes connect as clients over TCP or a Unix socket and multiplex packets through the owner. This mirrors Python behavior and uses msgpack RPC compatible with RNS 1.3.4 layouts.
Go CLI tools such as rgostatus dial this RPC. On Linux, Python rnsd defaults to a Unix abstract socket unless T383838shared_instance_type = tcp. Setup for mixed Go and Python tooling is in CLI utilities.
Storage (T383838internal/storage)
The daemon persists ratchets, identity blobs, destination tables, and related artifacts under T383838~/.reticulum-go/storage/. Library embedders can use the same paths or keep tables in memory with inmemorypathtable and inmemoryknowndestinations.
Set T383838in_memory_storage = yes (or T383838RETICULUM_IN_MEMORY_STORAGE=1) for fully ephemeral operation: no transport identity file, no blackhole directory, no split-resource staging on disk, and no T383838~/.reticulum-go bootstrap. Empty ConfigPath with no T383838RETICULUM_STORAGE_PATH also stays off disk. Soft caps (T383838max_in_memory_paths, T383838max_in_memory_known_destinations, T383838max_packet_hashlist, T383838soft_memory_limit) always bound RAM for the path table, known destinations, and packet hash filter. The split-resource byte budget still applies only under explicit in-memory storage.
Inbound packet flow
T282828
Wire bytes
|
v
Interface read loop
|
v
ProcessIncoming (IFAC verify, frame decode)
|
v
packetCallback -> Transport.HandlePacket
|
+-- PacketTypeAnnounce -> path table update, handler dispatch
+-- PacketTypeLink -> link state machine
+-- PacketTypeProof -> proof handling
+-- PacketTypeData -> forward, relay, or deliver to Destination.Receive
Key functions (for code navigation):
• T383838BaseInterface.ProcessIncoming in T383838pkg/interfaces/interface.go
• T383838Transport.HandlePacket in T383838pkg/transport/transport.go
• T383838Transport.handleTransportPacket for data context routing
Outbound packet flow
T282828
Application sends via Destination or Link
|
v
Transport.SendPacket
|
v
Path lookup (may rewrap as header type 2 for multi-hop)
|
v
Packet.Serialize
|
v
Interface.ProcessOutgoing (IFAC mask)
|
v
Wire bytes
If no path exists, transport may emit path requests according to configuration and watched destinations.
Concurrency model
• Each interface runs its own read loop (or shares a backbone hub poller). Stream interfaces (TCP, QUIC, VSOCK, WebTransport, I2P, Local, Pipe, backbone hub) read 64 KiB at a time. HDLC still splits frames at the packet MTU.
• Transport HandlePacket copies the frame then hands it to a fixed worker pool (T383838max_packet_handlers, default 512). Overflow sheds under dos_protection instead of spawning more goroutines.
• Links run session goroutines for keepalive, request/response, and channel outlets.
• Hot reload takes reloadMu on Node to swap interfaces without tearing down unrelated state.
Backbone I/O can consolidate many TCP sockets behind one epoll, kqueue, or iouring hub (T383838pkg/backbone). Configure with backboneio in T383838[reticulum].
Deployment patterns
Standalone node
One T383838reticulum-go process with local interfaces. Suitable for gateways, radios, and servers.
T282828
[Internet or LAN] <--> UDP/TCP Interface <--> reticulum-go <--> Your app
Shared instance
Multiple processes, one interface owner. Useful when a single radio or tunnel must be shared.
T282828
App A ----
App B -----+---- TCP/Unix shared instance ---- reticulum-go (interface owner)
App C ----/
Embedded library
A Go service links T383838pkg/node directly. No daemon. The service loads config, starts Node, and registers destinations in-process.
Browser WASM
T383838reticulum-wasm compiles transport and a WebSocket interface. JavaScript calls T383838reticulum.init, connect, announce, and related functions exposed by T383838pkg/wasm.
Control API sidecar
Non-Go applications talk HTTP and WebSocket to T383838pkg/controlapi on localhost while the daemon owns transport. See Control API.
librns in-process
Native hosts link T383838librns.so and call T383838include/rns.h. Same stack as T383838pkg/node, no separate daemon. Linux first. Odin hosts can use T383838bindings/odin. See librns.
Firecracker microvm
T383838microvm/ packages a static guest rootfs and a host vsock bridge for nested or isolated nodes. Default networking keeps clearnet on the host and pipes the guest over Firecracker vsock. See Firecracker microvm.
Persistence and state
┌────────────────────────────────────────┬─────┬───────────────────────────────────────────────────┐
│ State │ De… │ Notes │
├────────────────────────────────────────┼─────┼───────────────────────────────────────────────────┤
│ Config │ T383838~/… │ INI format, Python-compatible keys │
│ Path table │ T383838st… │ Optional RAM-only mode │
│ Known destinations │ T383838st… │ Loads Python-format files │
│ Identities │ T383838st… │ Per-hash blobs │
│ Known-peer ratchet public keys │ T383838st… │ Python-compatible T383838{ratchet, received} │
│ Local destination ratchet private keys │ Pa… │ Signed msgpack list, or RAM via T383838EnableRatchetsIn… │
│ Blackhole table │ T383838st… │ msgpack │
│ Transport identity │ T383838st… │ Used when transport enabled │
└────────────────────────────────────────┴─────┴───────────────────────────────────────────────────┘
Security boundaries
Cryptography is centralized in T383838pkg/cryptography and T383838pkg/identity. IFAC adds an optional outer authentication layer on interface frames. The runtime sandbox limits filesystem and privilege exposure after startup. Neither replaces correct key handling or network segmentation.
See Cryptography and Security.
Extension points
┌─────────────────────────┬────────────────────────────────────────────────────────────────────────┐
│ Extension │ Mechanism │
├─────────────────────────┼────────────────────────────────────────────────────────────────────────┤
│ Custom crypto for tests │ T383838cryptography.SetProvider │
│ Hardware signing │ T383838identity.NewIdentityWithSigner with T383838cryptography.Ed25519Signer │
│ Embedder lifecycle │ T383838node.Node hooks and control API lifecycle routes │
│ New interface types │ Implement T383838interfaces.Interface, register in T383838fromconfig.go │
│ Non-Go clients │ Control API (out-of-process), librns (in-process C ABI), T383838bindings/odi… │
└─────────────────────────┴────────────────────────────────────────────────────────────────────────┘
Adding a new interface type or changing on-wire layouts requires coordinated updates across implementations and crossref vectors.
What this stack does not include
• IP routing or DNS replacement
• Built-in application protocols (LXMF, MF, and RRC live in reticulum-go-protocols. NomadNet and similar stay in other projects)
• RNode firmware or serial radio drivers
• Post-quantum algorithms
Those may integrate over Reticulum destinations and links but are out of scope for this repository.
Served by rngit 1.5.2 - Generated in 0.04s